package cn.tedu.csmall.product.service.impl;


import cn.tedu.csmall.product.ex.ServiceException;
import cn.tedu.csmall.product.mapper.BrandCategoryMapper;
import cn.tedu.csmall.product.mapper.BrandMapper;
import cn.tedu.csmall.product.mapper.SpuMapper;
import cn.tedu.csmall.product.pojo.dto.BrandAddNewDTO;
import cn.tedu.csmall.product.pojo.dto.BrandUpdateDTO;
import cn.tedu.csmall.product.pojo.dto.CategoryUpdateDTO;
import cn.tedu.csmall.product.pojo.entity.Album;
import cn.tedu.csmall.product.pojo.entity.Brand;
import cn.tedu.csmall.product.pojo.entity.Category;
import cn.tedu.csmall.product.pojo.vo.AlbumStandardVO;
import cn.tedu.csmall.product.pojo.vo.BrandCategoryListItemVO;
import cn.tedu.csmall.product.pojo.vo.BrandListItemVO;
import cn.tedu.csmall.product.pojo.vo.BrandStandardVO;
import cn.tedu.csmall.product.repo.IBrandRedisRepository;
import cn.tedu.csmall.product.service.IBrandService;
import cn.tedu.csmall.product.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
public class BrandServiceImpl implements IBrandService {
    @Autowired
    private BrandMapper brandMapper;
    @Autowired
    private BrandCategoryMapper brandCategoryMapper;
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private IBrandRedisRepository iBrandRedisRepository;


    public BrandServiceImpl(){
        log.debug("创建业务对象:BrandServiceImpl");
    }

    @Override
    public void addNew(BrandAddNewDTO brandAddNewDTO) {
        log.debug("从现在开始处理添加品牌服务,请求参数{}",brandAddNewDTO);
        // 从参数对象中获取品牌名称
        String name = brandAddNewDTO.getName();
        // 检查品牌名称是否已经被占用（相册表中是否已经存在此名称的数据）
        int count = brandMapper.countByName(name);
        log.debug("检查品牌名称是否被占用");
        if (count>0){
            // 是：品牌名称已经被占用，添加品牌失败，抛出异常
            String message ="品牌名称已经被占用，添加品牌失败";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
            }

        // 否：品牌名称没有被占用，则向品牌表中插入数据
        log.debug("品牌名称已经被占用，添加品牌失败");

        Brand brand = new Brand();
        BeanUtils.copyProperties(brandAddNewDTO,brand);
        log.debug("即将插入数据");
        int rows = brandMapper.insert(brand);
        if (rows != 1 ){
            String message = "添加品牌失败,服务器忙稍后再试";
            log.debug(message);
            throw  new ServiceException(ServiceCode.ERR_INSERT,message);
        }
        log.debug("插入数据完成");
    }

    @Override
    public void delete(Long id){
        log.debug("开始处理[根据id删除相册]的业务,参数{}",id);
        // 调用Mapper对象的getStandardById()执行查询
        BrandStandardVO standardById = brandMapper.getStandardById(id);
        // 判断查询结果是否为null
        if (standardById==null) {
            // 是：无此id对应的数据，将不允许执行删除操作，则抛出异常
            String message = "删除品牌失败，尝试访问的数据不存在";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        //检查是否存在图片(picture) 关联到此相册,不许允许删除此相册
        int count = brandCategoryMapper.countByBrandId(id);
        if (count > 0){
            log.debug("{}",count);
            String message = "删除品牌失败,此品牌存在关联的类别数据";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        //检查是否存在图片(picture) 关联到此相册,不许允许删除此相册
        int counts = spuMapper.countByBrandId(id);
        if (counts>0){
            log.debug("{}",counts);
            String message = "删除品牌失败,此品牌存在关联的SPU数据";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        // 调用Mapper对象的deleteById()方法执行删除
        int row = brandMapper.deleteById(id);
        if (row != 1 ){
            String message = "删除品牌失败,服务器忙稍后再试";
            log.debug(message);
            throw  new ServiceException(ServiceCode.ERR_DELETE,message);
        }

    }

    @Override
    public List<BrandListItemVO> list(){
        log.debug("开始处理查询品牌列表业务");
//        List<BrandListItemVO> list = brandMapper.list();
//        brandRedisRepository.save(list);
        return iBrandRedisRepository.list();
    }

    //启用
    @Override
    public void setEnable(Long id){
        updateEnableById(id,1);
    }

    //禁用
    @Override
    public void setDisable(Long id){
        updateEnableById(id,0);
    }

    public void updateEnableById(Long id , Integer enable){
        String[] s={"禁用","启用"};
        //判断id是否为1
        if (id==1){
            String message = s[enable]+"品牌失败,这个id不能动";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        //判断查询的id有没有
        BrandStandardVO standardById = brandMapper.getStandardById(id);
        if (standardById == null){
            String message = s[enable]+"品牌失败,没有这个id";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }

        if (standardById.getEnable()==enable){
            String message = s[enable]+"品牌失败,enable相同";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        Brand brand = new Brand();
        brand.setId(id);
        brand.setEnable(enable);
        int rows = brandMapper.updateById(brand);
        if (rows!=1){
            String message = "服务器繁忙,请稍后再试";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
    }

    @Override
    public BrandStandardVO selectById(Long id){
        log.debug("开始处理根据id查看详情的服务");
        //根据id从缓存中获取数据
        log.debug("将从Redis中获取相关数据");
        BrandStandardVO brandStandardVO = iBrandRedisRepository.get(id);
        //判断获取到的数据是否不为null
        if (brandStandardVO != null){
            return brandStandardVO;
        }
        //没有的话,从数据库中查找
        BrandStandardVO standardById = brandMapper.getStandardById(id);
        if (standardById == null){
            String message = "查询失败,没有这个数据";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        //把数据库中的数据写入缓存中
        log.debug("将从数据库中获取相关数据,并存入到redis中");
        iBrandRedisRepository.save(standardById);
        return standardById;
    }


    @Override
    public void update(Long id,BrandUpdateDTO brandUpdateDTO){
        log.debug("开始修改详情");

        String name = brandUpdateDTO.getName();
        int rows = brandMapper.countByName(name);
        if (rows >= 1){
            String message = "修改失败,名字已存在";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        Brand brand = new Brand();
        BeanUtils.copyProperties(brandUpdateDTO,brand);
        rows = brandMapper.updateById(brand);
        if (rows != 1){
            String message = "修改失败,服务器繁忙";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
    }

    @Override
    public void rebuildCache() {
        log.debug("CachePreload.run()");

        log.debug("准备删除Redis缓存中的品牌数据……");
        iBrandRedisRepository.deleteAll();
        log.debug("删除Redis缓存中的品牌数据完毕");

        log.debug("准备从数据库中读取品牌列表……");
        List<BrandListItemVO> list = brandMapper.list();
        log.debug("从数据库中读取品牌列表，完成！");


        log.debug("准备将品牌列表写入到Redis缓存……");
        iBrandRedisRepository.save(list);
        log.debug("将品牌列表写入到Redis缓存，完成！");

        log.debug("准备将品牌详情写入到Redis缓存……");
        for (BrandListItemVO brandListItemVO : list) {
            Long id = brandListItemVO.getId();
            BrandStandardVO standardById = brandMapper.getStandardById(id);
            iBrandRedisRepository.save(standardById);
        }
        log.debug("将品牌详情写入到Redis缓存，完成！");
    }

}
